<template>
  <div
    class="datepicker"
    :class="{
      datepicker__clearable: clearable && text && !disabled,
    }"
  >
    <input
      readonly
      :value="text"
      :class="[show ? 'focus' : '', inputClass]"
      :disabled="disabled"
      :placeholder="placeholder"
      :name="name"
      v-if="type !== 'inline'"
    />
    <a id="closeIconId" class="datepicker-close" @click.stop="clear"></a>
    <transition name="datepicker-anim" @afterLeave="onAfterLeave">
      <div
        class="datepicker-popup"
        :class="[popupClass, { 'datepicker-inline': type === 'inline' }]"
        tabindex="-1"
        v-if="show || type === 'inline'"
      >
        <month-panel v-model="selectVal" :multiple="multiple"></month-panel>

        <div v-if="showButtons" class="datepicker__buttons">
          <button
            @click.prevent.stop="cancel"
            class="datepicker__button-cancel"
          >
            {{ this.local.cancelTip }}
          </button>
          <button
            @click.prevent.stop="confirm"
            class="datepicker__button-comfirm"
          >
            {{ this.local.confirmTip }}
          </button>
        </div>
      </div>
    </transition>
  </div>
</template>

<script>
import MonthPanel from "./month-panel.vue";
export default {
  name: "multiple-month",
  components: { MonthPanel },
  props: {
    name: [String],
    inputClass: [String],
    popupClass: [String],
    value: [Date, Array, String],
    disabled: [Boolean],
    type: {
      type: String,
      default: "normal",
    },
    placeholder: [String],
    local: {
      type: Object,
      default() {
        return {
          dow: 1, // Monday is the first day of the week
          hourTip: "选择小时", // tip of select hour
          minuteTip: "选择分钟", // tip of select minute
          secondTip: "选择秒数", // tip of select second
          yearSuffix: "年", // format of head
          monthsHead:
            "1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月".split("_"), // months of head
          months:
            "一月_二月_三月_四月_五月_六月_七月_八月_九月_十月_十一月_十二月".split(
              "_"
            ), // months of panel
          weeks: "一_二_三_四_五_六_日".split("_"), // weeks
          cancelTip: "取消", // default text for cancel button
          confirmTip: "确定", // default text for confirm button
        };
      },
    },
  },
  data() {
    return {
      multiple: true,
      show: false,
      selectVal: [],
      separator: ",",
      showButtons: false,
      clearable: true,
      format: "YYYY-MM",
    };
  },
  computed: {
    text() {
      return this.computedText();
    },
  },
  watch: {
    value(val) {
      this.selectVal = this.tfDateArray(val);
    },
  },
  methods: {
    tfDateArray(val) {
      if (Array.isArray(val)) {
        return val;
      } else {
        if (typeof val === "string" && val.indexOf(",") !== -1) {
          return val.split(",").map((item) => {
            if (item) {
              return item;
            }
          });
        }
        return val ? new Array(val) : [];
      }
    },
    tf(time, format) {
      const year = time.getFullYear();
      const month = time.getMonth();
      const day = time.getDate();
      const hours24 = time.getHours();
      const hours = hours24 % 12 === 0 ? 12 : hours24 % 12;
      const minutes = time.getMinutes();
      const seconds = time.getSeconds();
      const milliseconds = time.getMilliseconds();
      const dd = (t) => ("0" + t).slice(-2);
      const map = {
        YYYY: year,
        MM: dd(month + 1),
        MMM: this.local.months[month],
        MMMM: this.local.monthsHead[month],
        M: month + 1,
        DD: dd(day),
        D: day,
        HH: dd(hours24),
        H: hours24,
        hh: dd(hours),
        h: hours,
        mm: dd(minutes),
        m: minutes,
        ss: dd(seconds),
        s: seconds,
        S: milliseconds,
      };
      return (format || this.format).replace(
        /Y+|M+|D+|H+|h+|m+|s+|S+/g,
        (str) => map[str]
      );
    },
    getEmitVal() {
      if (this.multiple && Array.isArray(this.selectVal)) {
        const v = this.selectVal
          .map((date) => this.tf(new Date(date)))
          .join(`${this.separator}`);
        return v;
      } else {
        return this.selectVal;
      }
    },
    computedText() {
      if (this.value) {
        this.selectVal = this.tfDateArray(this.value);
        return this.value;
      }
    },
    clear() {
      this.selectVal = [];
      this.$emit("clear");
      this.$emit("input", "");
    },
    confirm() {
      const emitVal = this.getEmitVal();
      this.$emit("input", emitVal);
      this.$emit("confirm", emitVal);
      this.show = false;
    },
    cancel() {
      this.selectVal = [];
      this.$emit("input", "");
      this.$emit("cancel", "");
      this.show = false;
    },
    onClickMonth() {
      const emitVal = this.getEmitVal();
      this.$emit("input", emitVal);
      this.$emit("onClickMonth", emitVal);
    },
    onChange() {
      const emitVal = this.getEmitVal();
      this.$emit("input", emitVal);
      this.$emit("change", emitVal);
    },
    showPanel(e) {
      if (!(e.target.id === "closeIconId" && !this.show)) {
        this.show = this.$el.contains(e.target) && !this.disabled;
      }
    },
    onAfterLeave() {
      this.$emit("input", this.getEmitVal());
    },
  },
  mounted() {
    document.addEventListener("click", this.showPanel, true);
  },
  beforeDestroy() {
    document.removeEventListener("click", this.showPanel, true);
  },
};
</script>

<style>
.datepicker {
  display: inline-block;
  position: relative;
}

.datepicker:before {
  content: "";
  display: block;
  position: absolute;
  width: 34px;
  height: 100%;
  top: 0;
  right: 0;
  background: url("")
    no-repeat 50% 50%;
}

.datepicker-close {
  display: none;
  position: absolute;
  width: 34px;
  height: 100%;
  top: 0;
  right: 0;
  cursor: pointer;
}

.datepicker-close:before {
  display: block;
  content: "";
  position: absolute;
  width: 16px;
  height: 16px;
  left: 50%;
  top: 50%;
  margin-left: -8px;
  margin-top: -8px;
  text-align: center;
  background: #ccc;
  color: #fff;
  border-radius: 50%;
  background: #ccc
    url("")
    no-repeat 50% 50%;
}

.datepicker__clearable:hover:before {
  display: none;
}
.datepicker__clearable:hover .datepicker-close {
  display: block;
}

.datepicker-close:hover:before {
  background-color: #afafaf;
}

.datepicker > input {
  color: #666;
  transition: all 200ms ease;
  border: 1px solid #e5e5e5;
  height: 34px;
  box-sizing: border-box;
  outline: none;
  padding: 0 34px 0 12px;
  font-size: 14px;
  width: 100%;
  user-select: none;
  -ms-user-select: none;
  -moz-user-select: none;
  -webkit-user-select: none;
}

.datepicker > input.focus {
  border-color: #3bb4f2;
  -webkit-box-shadow: 0 0 5px rgba(59, 180, 242, 0.3);
  box-shadow: 0 0 5px rgba(59, 180, 242, 0.3);
}

.datepicker > input:disabled {
  cursor: not-allowed;
  background-color: #ebebe4;
  border-color: #e5e5e5;
  -webkit-box-shadow: none;
  box-shadow: none;
}

.datepicker-popup {
  position: absolute;
  transition: all 200ms ease;
  opacity: 1;
  transform: scaleY(1);
  transform-origin: center top;
  font-size: 12px;
  background: #fff;
  border: 1px solid #d9d9d9;
  box-shadow: 0 1px 6px rgba(99, 99, 99, 0.2);
  margin-top: 2px;
  outline: 0;
  padding: 5px;
  overflow: hidden;
  z-index: 999;
}

.datepicker-inline {
  position: relative;
  margin-top: 0;
}

.datepicker-bottom {
  float: left;
  width: 100%;
  text-align: right;
}

.datepicker-btn {
  padding: 5px 10px;
  background: #1284e7;
  color: #fff;
  border-radius: 2px;
  display: inline-block;
  cursor: pointer;
}
.datepicker-anim-enter-active {
  transform-origin: 0 0;
  animation: datepicker-anim-in 0.2s cubic-bezier(0.23, 1, 0.32, 1);
}

.datepicker-anim-leave-active {
  transform-origin: 0 0;
  animation: datepicker-anim-out 0.2s cubic-bezier(0.755, 0.05, 0.855, 0.06);
}

.datepicker__buttons {
  display: block;
  text-align: right;
}

.datepicker__buttons button {
  display: inline-block;
  font-size: 13px;
  border: none;
  cursor: pointer;
  margin: 10px 0 0 5px;
  padding: 5px 15px;
  color: #ffffff;
}

.datepicker__buttons .datepicker__button-comfirm {
  background: #1284e7;
  border-radius: 3px;
}

.datepicker__buttons .datepicker__button-cancel {
  border-radius: 3px;
  background: #666;
}

@keyframes datepicker-anim-in {
  0% {
    opacity: 0;
    transform: scaleY(0.8);
  }
  to {
    opacity: 1;
    transform: scaleY(1);
  }
}

@keyframes datepicker-anim-out {
  0% {
    opacity: 1;
    transform: scaleY(1);
  }
  to {
    opacity: 0;
    transform: scaleY(0.8);
  }
}
</style>
